﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Net.Sockets;
using System.Threading;

namespace PIM_ATE.rflight
{
    class ClsRfPimCmd_ControlSoftware
    {//纳特设备指令集
        //const int PORT = 5044;
        const int TIMEOUT = 100;
        const string NEW_LINE = "\n";
        bool m_isDebug = false;
        string m_error;
        TcpClient m_tcpObj;
        NetworkStream m_netObj;
        double ranMax = -115;
        double ranMin = -120;
        double Tx1 = 0;
        double Tx2 = 0;
        string m_msg = "";
        public ClsRfPimCmd_ControlSoftware(bool isDebug = false)
        {
            SetDebug(isDebug);
        }
        public void SetDebug(bool isDebug)
        {
            m_isDebug = isDebug;
        }
        public void SetDebugMaxMin(double max, double min)
        {
            if (max != 0 && min != 0)
            {
                ranMax = max;
                ranMin = min;
            }
            else
            {
                ranMax = -115;
                ranMin = -120;
            }
        }
        public bool Connect(string ip, int port = 50000)
        {
            if (m_isDebug) return true;
            try
            {
                m_tcpObj = new TcpClient();
                m_tcpObj.Connect(ip, port);
                m_netObj = m_tcpObj.GetStream();
                return true;
            }
            catch (Exception ex)
            {
                m_error = ex.Message;
                return false;
            }
        }
        public void Close()
        {
            if (m_tcpObj != null)
            {
                if (m_tcpObj.Connected)
                {
                    m_netObj.Close();
                }
                m_tcpObj.Close();
            }
        }
        bool sendMsg(string cmd, out string msg)
        {
            msg = "";
            byte[] message = Encoding.ASCII.GetBytes(cmd);
            try
            {
                m_netObj.Write(message, 0, message.Length);
            }
            catch (Exception ex)
            {
                m_error += "sendMsg: net error" + ex.Message; return false;
            }
            return isNAK(out msg);
        }
        string readMsg()
        {
            int count = 0;
            byte[] read = new byte[102400];
            for (int i = 0; i < TIMEOUT; i++)
            {
                if (m_tcpObj.Available > 0)
                {
                    try
                    {
                        count = m_netObj.Read(read, 0, read.Length);
                    }
                    catch (Exception ex)
                    {
                        m_error = "readMsg: net error" + ex.Message;
                    }
                    break;
                }
                if (i == TIMEOUT - 1)
                {
                    m_error = "readMsg: timeout";
                    return "";
                }
                Thread.Sleep(100);
            }
            string ret = Encoding.ASCII.GetString(read, 0, count);
            return ret;
        }
        public bool setFreqBand(int index = 0)
        {//设置系统频段 -- 700索引0，800索引1，900索引2，1800索引3，2100索引5，2600索引6  "SYST:FREQ:BAND 0\n"
            if (m_isDebug) return true;
            m_error = "";
            string cmd = string.Format("SYST:FREQ:BAND {0}\n", index);
            m_msg = "";
            return sendMsg(cmd, out m_msg);
        }
        public bool setMeasMode(bool isREFL)
        {//设置系统测量模式（端口号）   设置系统测量模式为反射 "SYST:MEAS:MODE REFL\n"
            if (m_isDebug) return true;
            m_error = "";
            string cmd = "";
            if (isREFL)
            {
                cmd = string.Format("SYST:MEAS:MODE REFL\n");
            }
            else
            {
                cmd = string.Format("SYST:MEAS:MODE TRAN\n");
            }
            m_msg = "";
            return sendMsg(cmd, out m_msg);
        }
        public bool setFreqMode(bool isFIX = true)
        {//设置点频\扫频模式 "FREQ:MODE FIX\n"
            if (m_isDebug) return true;
            m_error = "";
            string cmd = "";
            if (isFIX)
                cmd = string.Format("FREQ:MODE FIX\n");
            else
                cmd = string.Format("FREQ:MODE SWE\n");
            m_msg = "";
            return sendMsg(cmd, out m_msg);
        }
        public bool setCarrFreq(double f1, double f2, string unit = "mhz")
        {//点频设置载波1、2频率;扫频设置起始终止频段范围  单位MHz  "CARR:FREQ 1805.0,1880.0\n"
            if (m_isDebug) return true;
            m_error = "";
            f1 = ToMhz(f1, unit);
            f2 = ToMhz(f2, unit);
            string cmd = string.Format("CARR:FREQ {0},{1}\n", f1, f2);
            m_msg = "";
            return sendMsg(cmd, out m_msg);
        }
        double ToMhz(double freq, string unit)
        {
            if (unit.ToLower() == ("ghz"))
            {
                freq *= 1000;
            }

            else if (unit.ToLower() == ("khz"))
            {
                freq /= 1000;
            }

            else if (unit.ToLower() == ("hz"))
            {
                freq /= 1000 * 1000;
            }

            else//默认为mhz
            { }
            return Math.Round(freq, 1);
        }
        public bool setPimOrd(int order = 3)
        {//设置系统互调阶数位3："SYST:PIM:ORD 3\n"
            if (m_isDebug) return true;
            m_error = "";
            string cmd = string.Format("SYST:PIM:ORD {0}\n", order);
            m_msg = "";
            return sendMsg(cmd, out m_msg);
        }
        public bool setCarrPow(double power = 43.00)
        {//设置载波1、2的功率为43.00 dBm："CARR:POW 43.00\n"
            Tx1 = Tx2 = power;
            if (m_isDebug) return true;
            m_error = "";
            string cmd = string.Format("CARR:POW {0}\n", Math.Round(power, 2));
            m_msg = "";
            return sendMsg(cmd, out m_msg);
        }
        public bool getCarrPow(ref double p1, ref double p2)
        {//查询载波功率："CARR:POW?\n"
            if (m_isDebug)
            {
                p1 = p2 = Tx1;
                return true;
            }
            m_error = "";
            string cmd = string.Format("CARR:POW?\n");
            m_msg = "";

            if (!sendMsg(cmd, out m_msg))
            {
                m_error = "CARR:POW?: sendMsg net error";
                return false;
            }
            {
                if (m_msg.Replace("\n", "").Split(',').Length == 1)
                {
                    p1 = p2 = Convert.ToDouble(m_msg.Replace("\n", ""));
                }
                else
                {
                    p1 = Convert.ToDouble(m_msg.Replace("\n", "").Split(',')[0]);
                    p2 = Convert.ToDouble(m_msg.Replace("\n", "").Split(',')[1]);
                }


            }
            return true;
        }
        public bool setSystPimUnit(ImUnit unit = ImUnit.dBm)
        {//设置系统互调单位为dBm："SYST:PIM:UNIT dBm\n"
            if (m_isDebug) return true;
            m_error = "";
            string cmd = "";
            if (unit == ImUnit.dBm)
                cmd = string.Format("SYST:PIM:UNIT dBm\n");
            else
                cmd = string.Format("SYST:PIM:UNIT dBc\n");
            m_msg = "";
            return sendMsg(cmd, out m_msg);
        }
        public bool setMeasTime(int second = 5)
        {//设置系统测量时间为5秒："SYST:MEAS:TIME 5\n"
            if (m_isDebug) return true;
            m_error = "";
            string cmd = string.Format("SYST:MEAS:TIME {0}\n", second);
            m_msg = "";
            return sendMsg(cmd, out m_msg);
        }
        public bool setInitCont(bool isOpen = true)
        {//设置连续启动模式开启："INIT:CONT ON\n"   仅仅点频有效,开启了会连续测试至时间停止，不开启仅仅测试一个频点
            if (m_isDebug) return true;
            m_error = "";
            string cmd = "";
            if (isOpen)
                cmd = string.Format("INIT:CONT ON\n");
            else
                cmd = string.Format("INIT:CONT OFF\n");
            m_msg = "";
            return sendMsg(cmd, out m_msg);
        }
        public bool setInitImm(bool output = true)
        {//设置立即启动测试："INIT:IMM\n"
            /*（点频模式下，立即启动命令执行后，如果连续启动模式开启，则在系统测量时间内，互调仪连续测试；如果连续启动模式关闭，只点频测试一次。）
             	停止测试："OUTP:STAT OFF\n"
             */
            if (m_isDebug) return true;
            m_error = "";
            string cmd = "";
            if (output)
                cmd = string.Format("INIT:IMM\n");
            else
                cmd = string.Format("OUTP:STAT OFF\n");
            m_msg = "";
            return sendMsg(cmd, out m_msg);
        }
        public bool getOpc()
        {//连续查询测试完成状态："*OPC?\n"，直至返回状态为1。
            /*正常应答：“X\n”（ 1表示测试完成，0表示测试进行中）异常应答：“NAK\n”*/
            if (m_isDebug) return true;
            m_error = "";
            string cmd = string.Format("*OPC?\n");
            while (true)
            {
                m_msg = "";
                if (!sendMsg(cmd, out m_msg))
                {
                    m_error = "OPC: sendMsg net error";
                    return false;
                }
                else
                {
                    if (m_msg == "1\n" || m_msg == "OFF\n")
                    {
                        return true;
                    }
                    else if (m_msg == "0\n" || m_msg == "ON\n")
                    {
                        Thread.Sleep(50);
                        continue;
                    }
                }
            }
        }
        public bool getOpc_Time()
        {//连续查询测试完成状态："*OPC?\n"，直至返回状态为1。
            /*正常应答：“X\n”（ 1表示测试完成，0表示测试进行中）异常应答：“NAK\n”*/
            if (m_isDebug) return false;
            m_error = "";
            string cmd = string.Format("*OPC?\n");
            while (true)
            {
                m_msg = "";
                if (!sendMsg(cmd, out m_msg))
                {
                    m_error = "OPC: sendMsg net error";
                    return false;
                }
                else
                {
                    if (m_msg == "1\n" || m_msg == "OFF\n")
                    {
                        return true;
                    }
                    else if (m_msg == "0\n" || m_msg == "ON\n")
                    {
                        return false;
                    }
                }
            }
        }
        public bool getFixPimData(double freq, ref double dPimResult)
        {//查询点频互调数据："FIX:PIM:DATA?\n"
            /*正常应答：例如“890.0, -122.69\n”（890.0表示互调频率，-122.69表示互调功率）
             * 异常应答：“NAK\n”
             */
            if (m_isDebug)
            {
                Random ran = new Random(Guid.NewGuid().GetHashCode());
                int min = (int)(ranMin * 10);
                int max = (int)(ranMax * 10);
                dPimResult = ran.Next(min, max) / 10 + ran.NextDouble();
                dPimResult = Math.Round(dPimResult, 2);
                return true;
            }
            m_error = "";
            string cmd = string.Format("FIX:PIM:DATA?\n");

            m_msg = "";
            if (!sendMsg(cmd, out m_msg))
            {
                m_error = "result: sendMsg net error";
                return false;
            }
            else
            {
                string[] value = m_msg.Split(',');
                if (value.Length < 2)
                {
                    return false;
                }
                if (!double.TryParse(value[1], out dPimResult))
                {//互调获取
                    m_error = "result: PimResult error ==>" + m_msg;
                    return false;
                }
            }
            return true;
        }
        public bool setSweStep(double step = 1.0d)
        {//设置扫频步进为1 MHz："SWE:STEP 1.0\n"
            if (m_isDebug) return true;
            m_error = "SWE:STEP";
            string cmd = string.Format("SWE:STEP {0}\n", step);
            m_msg = "";
            return sendMsg(cmd, out m_msg);
        }
        public bool getSwePimTrac(ref Dictionary<string, string> dic, out bool isEND, bool isUp = true)
        {//查询上行扫频互调轨迹："SWE:UP:PIM:TRAC?\n"   下行同理  "SWE:DN:PIM:TRAC?\n"
            /*正常应答：例如“890.0, -122.69, 892.0, -122.37, 894.0, -122.45, 896.0, -122.93\n”（890.0表示上行扫频互调轨迹第一点的频率，-122.69表示上行扫频互调轨迹第一点的互调功率，以下诸如类推）
             */
            isEND = false;
            if (m_isDebug) return true;
            m_error = "";
            string cmd = "";
            if (isUp)
                cmd = string.Format("SWE:UP:PIM:TRAC?\n");
            else
                cmd = string.Format("SWE:DN:PIM:TRAC?\n");
            m_msg = "";
            if (!sendMsg(cmd, out m_msg))
            {
                m_error = "SWE:UP:PIM:TRAC?: sendMsg net error";
                return false;
            }
            if (m_msg.Contains("\n"))
            {//结束上行、下行
                isEND = true;
                m_msg.Replace("\n", "");
            }
            string[] arrRet = m_msg.Split(',');
            if (arrRet.Length > 1)
            {
                for (int i = 0; i < arrRet.Length; i += 2)
                {
                    if (!dic.ContainsKey(arrRet[i]))
                        dic.Add(arrRet[i], arrRet[i + 1]);
                }
            }
            return true;
        }
        public bool getSweCarrFreq(out List<string> F1, out List<string> F2, out bool isEND, bool isUp = true)
        {//查询上行扫频互调轨迹："SWE:UP:CARR:FREQ?\n"
            //正常应答：例如“925.0, 926.0, 927.0, 928.0, 960.0\n”（925.0表示上行扫频互调轨迹第一点载波1的频率，依次类推，928.0表示上行扫频互调轨迹截止点载波1的频率；960.0表示载波2的频率）
            //异常应答：“NAK\n”

            F1 = new List<string>();
            F2 = new List<string>();
            isEND = false;
            if (m_isDebug) return true;
            m_error = "";
            string cmd = "";
            if (isUp)
                cmd = string.Format("SWE:UP:CARR:FREQ?\n");
            else
                cmd = string.Format("SWE:DN:CARR:FREQ?\n");
            m_msg = "";
            if (!sendMsg(cmd, out m_msg))
            {
                m_error = "SWE:UP:CARR:FREQ?: sendMsg net error";
                return false;
            }
            if (m_msg.Contains("\n"))
            {//结束上行、下行
                isEND = true;
                m_msg.Replace("\n", "");
            }
            string[] arrRet = m_msg.Split(',');
            if (arrRet.Length > 1)
            {
                for (int i = F1.Count * 2; i < arrRet.Length; i += 2)
                {
                    F1.Add(arrRet[i]);
                    F2.Add(arrRet[i + 1]);
                }
            }
            return true;
        }
        public bool getSwePoint(ref List<JcPIMRunner.XPlot> lstXPlot, out bool isEND, ref double n1, ref double n2, bool isUp = true)
        {
            m_error = ""; m_msg = ""; isEND = false;
            string cmdF = "", cmdV = "", freq = "", val = "";
            if (isUp)
            {
                /********上行先看下行，下行有数据证明上行完成***************/
                cmdF = "SWE:DN:CARR:FREQ?\n";
                sendMsg(cmdF, out freq);
                if (freq.Split(',').Length > 1)
                {
                    isEND = true;
                }
                /********上行先看下行，下行有数据证明上行完成***************/

                cmdF = "SWE:UP:CARR:FREQ?\n";
                cmdV = "SWE:UP:PIM:TRAC?\n";
            }
            else
            {
                cmdF = "SWE:DN:CARR:FREQ?\n";
                cmdV = "SWE:DN:PIM:TRAC?\n";
            }
            if (!sendMsg(cmdF, out freq) || !sendMsg(cmdV, out val))
            {
                m_error = "SWE:CARR:FREQ?||SWE:PIM:TRAC?: sendMsg net error";
                return false;
            }
            //int co = 0;
            //do
            //{
            //    co++;
            //    sendMsg(cmdF, out freq);
            //    Thread.Sleep(10);
            //    sendMsg(cmdV, out val);
            //    Thread.Sleep(10);
            //}
            //while (freq == "" && val == "");

            //if (freq.Contains("\n") && val.Contains("\n"))
            //{
            //    isEND = true;
            //}
            //freq.Replace("\n", "");
            //val.Replace("\n", "");
            string[] ARRfreq = freq.Split(',');
            if (ARRfreq.Length < 2) return false;
            double[] dsARRfreq = Array.ConvertAll(ARRfreq, v1 => double.Parse(v1));
            string[] ARRval = val.Split(',');
            double[] dsARRval = Array.ConvertAll(ARRval, v1 => double.Parse(v1));
            int start = 0;
            if (isUp)
            {
                start = (int)n1 * 2 ;
                n1 = ARRfreq.Length / 2;
            }
            else
            {
                start = (int) n2* 2;
                n2 = ARRfreq.Length / 2;
            }
            for (int i = start; i < ARRfreq.Length; i += 2)
            {
                if (lstXPlot.IndexOf(new JcPIMRunner.XPlot(dsARRfreq[i], dsARRfreq[i + 1], dsARRval[i], dsARRval[i + 1])) < 0)
                    lstXPlot.Add(new JcPIMRunner.XPlot(dsARRfreq[i], dsARRfreq[i + 1], dsARRval[i], dsARRval[i + 1]));
            }
            return true;
        }
        public bool setIMFreqRang(double rxl, double rxh)
        {//            设置互调频率范围："IM:FREQ:RANG XXXX.X,YYYY.Y\n"
         //（注释：XXXX.X 表示互调起始频率，YYYY.Y 表示互调截止频率）
         //正常应答：“ACK\n”
         //异常应答：“NAK\n”
            if (m_isDebug) return true;
            m_error = ""; m_msg = "";
            string cmd = string.Format("IM:FREQ:RANG {0},{1}\n", rxl, rxh);
            if (!sendMsg(cmd, out m_msg))
            {
                m_error = "IM:FREQ:RANG : sendMsg net error";
                return false;
            }
            else
            {
                return true;
            }
        }
        public bool getErr()
        {
            /*
             * 35.	查询系统错误："SYST:ERR?\n"
正常应答：“XXXXXXXXXXXXXXX\n”（“No Error!\n”表示
无系统错误）
异常应答：“NAK\n”
             */
            if (m_isDebug) return true;
            m_error = ""; m_msg = "";
            string cmd = "SYST:ERR?\n";
            if (!sendMsg(cmd, out m_msg))
            {
                m_error = "SYST:ERR?: sendMsg net error";
                return false;
            }
            else
            {
                m_error = m_msg;
                if (m_msg == "No Error!\n")
                {
                    return true;
                }
                else
                {
                    return false;
                }
            }
        }

        bool isNAK(out string msg)
        {
            msg = readMsg();
            if (msg == "NAK\n")
            {
                return false;
            }
            else
            {
                return true;
            }
        }
        public string fnGetError()
        {
            return m_error;
        }


        double F1 = 0D;
        double F2 = 0D;
        public bool fnSetTxFreqs(double freq1, double freq2, string unit)
        {
            F1 = ToMhz(freq1, unit);
            F2 = ToMhz(freq2, unit);
            return true;
        }

    }
}
